package com.iotechn.unimall.app.api.enterprise;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.toolkit.StringUtils;
import com.iotechn.unimall.app.executor.GlobalExecutor;
import com.iotechn.unimall.core.exception.ServiceException;
import com.iotechn.unimall.data.component.CacheComponent;
import com.iotechn.unimall.data.domain.EnterpriseImageDO;
import com.iotechn.unimall.data.domain.SettingsImageDO;
import com.iotechn.unimall.data.mapper.EnterpriseImageMapper;
import com.iotechn.unimall.data.model.Page;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.Cursor;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;


@Service
public class EnterpriseServiceImpl implements EnterpriseService {

    private static final Logger logger = LoggerFactory.getLogger(EnterpriseServiceImpl.class);

    private static final String PLATFORM = "CA_PLATFORM";
    private static final String Enterprise_IMAGES_GROUP = "CA_Enterprise_IMAGES_GROUP";
    private static final String ENTERPRISE_INFO = "CA_ENTERPRISE_INFO";

    @Autowired
    private CacheComponent cacheComponent;
    @Autowired
    private EnterpriseImageMapper enterpriseImageMapper;

    @Value("${weather.slave}")
    private String weatherUrl;
    @Value("${weather.master.now}")
    private String weatherNow;
    @Value("${weather.master.3d}")
    private String weather3d;
    @Value("${weather.master.air}")
    private String weatherAir;
    @Value("${weather.master.key}")
    private String weatherKey;
    @Value("${map.analysisLatLngToAddress.api}")
    private String locationUrl;
    @Value("${map.key}")
    private String locationKey;

    private final static String[] PARAMS = {"company_*","slogan_*"};

    public enum IMAGE_TYPE{
        HOME_LOGO(1),
        HOME_BANNER(2),
        HOME_OTHER(3),
        NEWS_BANNER(4),
        HOME_WECHAT(5),
        HOME_YIFENTIAN(6),

        ;
        public int CODE;
        IMAGE_TYPE(int code){
            this.CODE = code;
        }
    }

    @Override
    public String info(String lng, String lat, String ip) throws ExecutionException, InterruptedException {

        JSONObject jsonObject = JSONObject.parseObject(bottom());
        Future future = GlobalExecutor.execute(new Task(lng, lat));
        // home banner && home other 待修改
        {
            JSONArray banner = new JSONArray();
            JSONArray other = new JSONArray();
            Set<SettingsImageDO> set = cacheComponent.getZsetWithScores(Enterprise_IMAGES_GROUP, (double) (IMAGE_TYPE.HOME_BANNER.CODE * 100), SettingsImageDO.class);
            ArrayList<SettingsImageDO> list = new ArrayList<>(set);
            list.sort(Comparator.comparing(SettingsImageDO::getOrder));
            list.forEach(s->{
                JSONObject json = new JSONObject();
                    json.put("image",s.getImageUrl());
                    json.put("link",s.getUrl());
                    banner.add(json);
            });
            set = cacheComponent.getZsetWithScores(Enterprise_IMAGES_GROUP, (double) (IMAGE_TYPE.HOME_OTHER.CODE * 100), SettingsImageDO.class);
            list.clear();
            list.addAll(set);
            list.sort(Comparator.comparing(SettingsImageDO::getOrder));
            list.forEach(s->{
                other.add(s.getImageUrl());
            });
            jsonObject.put("banner",banner.toJSONString());
            jsonObject.put("other",other.toJSONString());
        }
        // info
        {
            jsonObject.put("info",cacheComponent.getRaw(ENTERPRISE_INFO));
        }
        // weather
        {
            Object o = future.get();
            jsonObject.put("weather",o);
        }

        return jsonObject.toJSONString();
    }

    class Task implements Callable<String> {

        private String lng;
        private String lat;

        public Task(String lng, String lat) {
            this.lng = lng;
            this.lat = lat;
        }

        @Override
        public String call() throws IOException {
            OkHttpClient mOkHttpClient = new OkHttpClient();
            JSONObject result = new JSONObject();

            try {
                //当天天气 --获取 温度，风力，湿度
                StringBuilder url = new StringBuilder(weatherNow)
                        .append("location="+lng+","+lat)
                        .append("&key="+weatherKey);

                Request request = new Request.Builder().url(url.toString()).build();
                Response response = mOkHttpClient.newCall(request).execute();
                JSONObject jsonObject = JSONObject.parseObject(response.body().string());
                JSONObject now = jsonObject.getJSONObject("now");
                result.put("temp",now.get("temp").toString());
                result.put("windScale",now.get("windScale").toString());
                result.put("humidity",now.get("humidity").toString());

                //3天天气 -- 当天最高和最低气温
                url = new StringBuilder(weather3d)
                        .append("location="+lng+","+lat)
                        .append("&key="+weatherKey);

                request = new Request.Builder().url(url.toString()).build();
                response = mOkHttpClient.newCall(request).execute();
                jsonObject = JSONObject.parseObject(response.body().string());
                JSONArray daily = jsonObject.getJSONArray("daily");
                result.put("tempMax",daily.getJSONObject(0).get("tempMax").toString());
                result.put("tempMin",daily.getJSONObject(0).get("tempMin").toString());

                //当天空气质量 -- 获取pm2.5
                url = new StringBuilder(weatherAir)
                        .append("location="+lng+","+lat)
                        .append("&key="+weatherKey);

                request = new Request.Builder().url(url.toString()).build();
                response = mOkHttpClient.newCall(request).execute();
                jsonObject = JSONObject.parseObject(response.body().string());
                JSONObject air = jsonObject.getJSONObject("now");
                result.put("pm2p5",air.get("pm2p5").toString());

                return result.toJSONString();
            } catch (Exception e) {
                logger.error("[获取天气API异常]",e);
                return null;
            }
        }
    }

    @Override
    public String bottom() {
        JSONObject jsonObject = new JSONObject();
        {
            Set<SettingsImageDO> set = cacheComponent.getZsetWithScores(Enterprise_IMAGES_GROUP, (double) (IMAGE_TYPE.HOME_LOGO.CODE * 100), SettingsImageDO.class);
            set.forEach(s -> jsonObject.put("logo", s.getImageUrl()));
            set = cacheComponent.getZsetWithScores(Enterprise_IMAGES_GROUP, (double) (IMAGE_TYPE.HOME_WECHAT.CODE * 100), SettingsImageDO.class);
            set.forEach(s -> jsonObject.put("wechat", s.getImageUrl()));
        }
        {
            for (int i = 0; i < PARAMS.length; i++) {
                Cursor<Map.Entry<Object, Object>> hScanRaw = cacheComponent.getHScanRaw(PLATFORM, PARAMS[i], Integer.MAX_VALUE);
                while(hScanRaw.hasNext()){
                    Map.Entry<Object, Object> entry = hScanRaw.next();
                    jsonObject.put(entry.getKey().toString(),entry.getValue().toString());
                }
            }
        }
        return jsonObject.toJSONString();
    }
    @Override
    public List<EnterpriseImageDO> productInfo(){
        Wrapper<EnterpriseImageDO> wrapper = new EntityWrapper<EnterpriseImageDO>();
        wrapper.orderBy("id", false);
        List<EnterpriseImageDO> enterpriseImageDOS = enterpriseImageMapper.selectPage(new RowBounds(0, 4), wrapper);
        return enterpriseImageDOS;
    }

    @Override
    public Page<EnterpriseImageDO> productList(Integer page, Integer limit,String name) throws ServiceException {
        Wrapper<EnterpriseImageDO> wrapper = new EntityWrapper<EnterpriseImageDO>();
        if (!StringUtils.isEmpty(name))
            wrapper.like("name", name);
        wrapper.orderBy("id", false);
        Integer count = enterpriseImageMapper.selectCount(wrapper);
        List<EnterpriseImageDO> EnterpriseImageDOS = enterpriseImageMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
        return new Page<>(EnterpriseImageDOS, page, limit, count);
    }

    public String yimutianLunbotu(){
        JSONArray banner = new JSONArray();
        Set<SettingsImageDO> set = cacheComponent.getZsetWithScores(Enterprise_IMAGES_GROUP, (double) (IMAGE_TYPE.HOME_YIFENTIAN.CODE * 100), SettingsImageDO.class);
        ArrayList<SettingsImageDO> list = new ArrayList<>(set);
        list.sort(Comparator.comparing(SettingsImageDO::getOrder));
        list.forEach(s->{
            JSONObject json = new JSONObject();
            json.put("image",s.getImageUrl());
            json.put("link",s.getUrl());
            banner.add(json);
        });
        return banner.toJSONString();
    }

}
